<?php
namespace addons\weixin\library;

use addons\weixin\library\MessageRepositories;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Message\Article;
use EasyWeChat\Message\Image;
use EasyWeChat\Message\Material;
use EasyWeChat\Message\News;
use EasyWeChat\Message\Text;
use EasyWeChat\Message\Video;
use EasyWeChat\Message\Voice;
use EasyWeChat\Payment\Order;
use EasyWeChat\Server\Guard;
use app\admin\model\weixin\Reply as WechatReply;
use think\Response;
use think\Cookie;
use think\Session;

class WechatService
{

    private static $instance = null;

    private static $wxid = 0;



    public static function options()
    {

        $where["group"] = "weixin";
        if(self::$wxid == 0){
            file_put_contents("wechat_data0000.json",date("Y-m-d H:i:s",time())."写入数据1：".var_export(self::$wxid,true).PHP_EOL , FILE_APPEND);
            $wxid = Session::get('wxid');
            $where["wx_id"] = $wxid;
        }else{
            file_put_contents("wechat_data111111.json",date("Y-m-d H:i:s",time())."写入数据1：".var_export(self::$wxid,true).PHP_EOL , FILE_APPEND);
            $wxid = self::$wxid;

            $where["wx_id"] = $wxid;
        }





        $wechat_data = \app\admin\model\weixin\Config::where($where)->select();


        file_put_contents("wechat_data.json",date("Y-m-d H:i:s",time())."写入数据1：".var_export($wechat_data,true).PHP_EOL , FILE_APPEND);

        foreach ($wechat_data as $k => $v) {
            $value = $v->toArray();
            if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
                $value['value'] = explode(',', $value['value']);
            }
            if ($value['type'] == 'array') {
                $value['value'] = (array)json_decode($value['value'], true);
            }
            $wechat[$value['name']] = $value['value'];
        }

        $config = [
            'app_id' => isset($wechat['appid']) ? trim($wechat['appid']) : '',
            'secret' => isset($wechat['appsecret']) ? trim($wechat['appsecret']) : '',
            'token'  => isset($wechat['token']) ? trim($wechat['token']) : '',
            'guzzle' => [
                'timeout' => 10.0, // 超时时间（秒）
                'verify'  => false
            ],
        ];
        if (isset($wechat['encode']) && (int)$wechat['encode']>0 && isset($wechat['encodingaeskey']) &&
            !empty($wechat['encodingaeskey'])) {
            $config['aes_key'] = $wechat['encodingaeskey'];
        }

        return $config;
    }

    public static function application($cache = false)
    {

        (self::$instance === null || $cache === true) && (self::$instance = new Application(self::options()));
        return self::$instance;
    }

    public static function serve($wxid):Response
    {

        self::$wxid = $wxid;
        $wechat = self::application(true);
        $server = $wechat->server;
        self::hook($server);
        $response = $server->serve();

        file_put_contents("response.json",date("Y-m-d H:i:s",time())."写入数据1：".var_export($response,true).PHP_EOL , FILE_APPEND);


        //关注后 写入对应表 并绑定公众号
        $wxXml = $response->getContent();
        file_put_contents("getwxXml.json",date("Y-m-d H:i:s",time())."写入数据1：".var_export($wxXml,true).PHP_EOL , FILE_APPEND);
        $xml_parser = xml_parser_create();
        //判断微信返回的是否是xml 数据 验证token 时 是非xml数据
        if(xml_parse($xml_parser,$wxXml,true)){
            $obj = simplexml_load_string($wxXml, 'SimpleXMLElement', LIBXML_NOCDATA);

            $eJSON = json_encode($obj);
            $dJSON = json_decode($eJSON);
            $toUserName = $dJSON->ToUserName;//获取"ToUserName"对应的值

            //先判断是否已经关注过，如果存在则不再写入数据

            if($toUserName){
                $info =  \app\admin\model\User::where(["openid"=>$toUserName])->find();
                if(!$info){
                    $data["group_id"] = 2;
                    $data["createtime"] = time();
                    $data["status"] = "normal";
                    $data["from"] = 1;
                    $data["wx_id"] = $wxid;
                    $data["openid"] = $toUserName;
                    $res =  \app\admin\model\User::insertGetId($data);
                    file_put_contents("getWechat.json",date("Y-m-d H:i:s",time())."写入数据：".var_export($res,true).PHP_EOL , FILE_APPEND);
                }

            }

        }else{
            xml_parser_free($xml_parser);
            file_put_contents("getWechatxmlerror.json",date("Y-m-d H:i:s",time())."写入数据：无".PHP_EOL , FILE_APPEND);
        }


        return response($response->getContent());
    }

    /**
     * 监听行为
     * @param Guard $server
     */
    private static function hook($server)
    {

        $server->setMessageHandler(function ($message) {
            //微信消息前置操作
            switch ($message->MsgType) {
                case 'event':
                    switch (strtolower($message->Event)) {
                        case 'subscribe':
                            $response = WechatReply::reply('subscribe',self::$wxid);//关注回复
                            break;
                        case 'unsubscribe':
                            //用户取消关注公众号前置操作
                            break;
                        case 'scan':
                            $response = WechatReply::reply('subscribe',self::$wxid);//扫码关注
                            break;
                        case 'location':
                            $response = MessageRepositories::wechatEventLocation($message);
                            break;
                        case 'click':
                            $response = WechatReply::reply($message->EventKey);//点击事件
                            break;
                        case 'view':
                            $response = MessageRepositories::wechatEventView($message);
                            break;
                    }
                    break;
                case 'text':
                    $response = WechatReply::reply($message->Content);
                    break;
                case 'image':
                    $response = MessageRepositories::wechatMessageImage($message);
                    break;
                case 'voice':
                    $response = MessageRepositories::wechatMessageVoice($message);
                    break;
                case 'video':
                    $response = MessageRepositories::wechatMessageVideo($message);
                    break;
                case 'location':
                    $response = MessageRepositories::wechatMessageLocation($message);
                    break;
                case 'link':
                    $response = MessageRepositories::wechatMessageLink($message);
                    break;
                // ... 其它消息
                default:
                    $response = MessageRepositories::wechatMessageOther($message);
                    break;
            }

            return $response ?? false;
        });
    }


    /**
     * 多客服消息转发
     * @param string $account
     * @return \EasyWeChat\Message\Transfer
     */
    public static function transfer($account = '')
    {
        $transfer = new \EasyWeChat\Message\Transfer();
        return empty($account) ? $transfer : $transfer->to($account);
    }


    /**
     * 上传永久素材接口
     * @return \EasyWeChat\Material\Material
     */
    public static function materialService()
    {
        return self::application()->material;
    }

    /**
     * 上传临时素材接口
     * @return \EasyWeChat\Material\Temporary
     */
    public static function materialTemporaryService()
    {
        return self::application()->material_temporary;
    }

    /**
     * 用户接口
     * @return \EasyWeChat\User\User
     */
    public static function userService()
    {
        return self::application()->user;
    }


    /**
     * 客服消息接口
     * @param null $to
     * @param null $message
     */
    public static function staffService()
    {
        return self::application()->staff;
    }

    /**
     * 微信公众号菜单接口
     * @return \EasyWeChat\Menu\Menu
     */
    public static function menuService()
    {
        return self::application()->menu;
    }

    /**
     * 微信二维码生成接口
     * @return \EasyWeChat\QRCode\QRCode
     */
    public static function qrcodeService()
    {
        return self::application()->qrcode;
    }

    /**
     * 短链接生成接口
     * @return \EasyWeChat\Url\Url
     */
    public static function urlService()
    {
        return self::application()->url;
    }

    /**
     * 用户授权
     * @return \Overtrue\Socialite\Providers\WeChatProvider
     */
    public static function oauthService()
    {


        return self::application()->oauth;
    }

    /**
     * 模板消息接口
     * @return \EasyWeChat\Notice\Notice
     */
    public static function noticeService()
    {
        return self::application()->notice;
    }

    public static function sendTemplate($wxid,$openid, $templateId, array $data, $url = null, $defaultColor = null)
    {
        self::$wxid = $wxid;
        $notice = self::noticeService()->to($openid)->template($templateId)->andData($data);
        if ($url !== null) {
            $notice->url($url);
        }
        if ($defaultColor !== null) {
            $notice->defaultColor($defaultColor);
        }
        return $notice->send();
    }

    public static function sendTemplateold($openid, $templateId, array $data, $url = null, $defaultColor = null)
    {
        $notice = self::noticeService()->to($openid)->template($templateId)->andData($data);
        if ($url !== null) {
            $notice->url($url);
        }
        if ($defaultColor !== null) {
            $notice->defaultColor($defaultColor);
        }
        return $notice->send();
    }

    /**
     * 支付
     * @return \EasyWeChat\Payment\Payment
     */
    public static function paymentService()
    {
        return self::application()->payment;
    }

    public static function downloadBill($day, $type = 'ALL')
    {
//        $payment = self::paymentService();
//        $merchant = $payment->getMerchant();
//        $params = [
//            'appid' => $merchant->app_id,
//            'bill_date'=>$day,
//            'bill_type'=>strtoupper($type),
//            'mch_id'=> $merchant->merchant_id,
//            'nonce_str' => uniqid()
//        ];
//        $params['sign'] = \EasyWeChat\Payment\generate_sign($params, $merchant->key, 'md5');
//        $xml = XML::build($params);
//        dump(self::paymentService()->downloadBill($day)->getContents());
//        dump($payment->getHttp()->request('https://api.mch.weixin.qq.com/pay/downloadbill','POST',[
//            'body' => $xml,
//            'stream'=>true
//        ])->getBody()->getContents());
    }

    public static function userTagService()
    {
        return self::application()->user_tag;
    }

    public static function userGroupService()
    {
        return self::application()->user_group;
    }

    /**
     * jsSdk
     * @return \EasyWeChat\Js\Js
     */
    public static function jsService()
    {
        return self::application()->js;
    }

    public static function jsSdk($url = '')
    {
        $apiList = [
            'editAddress', 'openAddress', 'updateTimelineShareData', 'updateAppMessageShareData', 'onMenuShareTimeline',
            'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'startRecord',
            'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'onVoicePlayEnd', 'uploadVoice',
            'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'translateVoice',
            'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'hideMenuItems',
            'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'closeWindow', 'scanQRCode',
            'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard'
        ];
        $jsService = self::jsService();
        if ($url) {
            $jsService->setUrl($url);
        }
        try {
            return $jsService->config($apiList);
        } catch (\Exception $e) {
            return '{}';
        }
    }

    /**
     * 回复文本消息
     * @param string $content 文本内容
     * @return Text
     */
    public static function textMessage($content)
    {
        return new Text(compact('content'));
    }

    /**
     * 回复图片消息
     * @param string $media_id 媒体资源 ID
     * @return Image
     */
    public static function imageMessage($media_id)
    {
        return new Image(compact('media_id'));
    }

    /**
     * 回复视频消息
     * @param string $media_id 媒体资源 ID
     * @param string $title 标题
     * @param string $description 描述
     * @param null $thumb_media_id 封面资源 ID
     * @return Video
     */
    public static function videoMessage($media_id, $title = '', $description = '...', $thumb_media_id = null)
    {
        return new Video(compact('media_id', 'title', 'description', 'thumb_media_id'));
    }

    /**
     * 回复声音消息
     * @param string $media_id 媒体资源 ID
     * @return Voice
     */
    public static function voiceMessage($media_id)
    {
        return new Voice(compact('media_id'));
    }

    /**
     * 回复图文消息
     * @param string|array $title 标题
     * @param string $description 描述
     * @param string $url URL
     * @param string $image 图片链接
     */
    public static function newsMessage($title, $description = '...', $url = '', $image = '')
    {
        if (is_array($title)) {
            if (isset($title[0]) && is_array($title[0])) {
                $newsList = [];
                foreach ($title as $news) {
                    $newsList[] = self::newsMessage($news);
                }
                return $newsList;
            } else {
                $data = $title;
            }
        } else {
            $data = compact('title', 'description', 'url', 'image');
        }
        return new News($data);
    }

    /**
     * 回复文章消息
     * @param string|array $title 标题
     * @param string $thumb_media_id 图文消息的封面图片素材id（必须是永久 media_ID）
     * @param string $source_url 图文消息的原文地址，即点击“阅读原文”后的URL
     * @param string $content 图文消息的具体内容，支持HTML标签，必须少于2万字符，小于1M，且此处会去除JS
     * @param string $author 作者
     * @param string $digest 图文消息的摘要，仅有单图文消息才有摘要，多图文此处为空
     * @param int $show_cover_pic 是否显示封面，0为false，即不显示，1为true，即显示
     * @param int $need_open_comment 是否打开评论，0不打开，1打开
     * @param int $only_fans_can_comment 是否粉丝才可评论，0所有人可评论，1粉丝才可评论
     * @return Article
     */
    public static function articleMessage($title, $thumb_media_id, $source_url, $content = '', $author = '', $digest = '', $show_cover_pic = 0, $need_open_comment = 0, $only_fans_can_comment = 1)
    {
        $data = is_array($title) ? $title : compact('title', 'thumb_media_id', 'source_url', 'content', 'author',
            'digest', 'show_cover_pic', 'need_open_comment', 'only_fans_can_comment');
        return new Article($data);
    }

    /**
     * 回复素材消息
     * @param string $type [mpnews、 mpvideo、voice、image]
     * @param string $media_id 素材 ID
     * @return Material
     */
    public static function materialMessage($type, $media_id)
    {
        return new Material($type, $media_id);
    }

    /**
     * 作为客服消息发送
     * @param $to
     * @param $message
     * @return bool
     */
    public static function staffTo($to, $message)
    {
        $staff = self::staffService();
        $staff = is_callable($message) ? $staff->message($message()) : $staff->message($message);
        $res = $staff->to($to)->send();
        return $res;
    }

    /**
     * 获得用户信息
     * @param array|string $openid
     * @return \EasyWeChat\Support\Collection
     */
    public static function getUserInfo($openid)
    {
        $userService = self::userService();
        $userInfo = is_array($openid) ? $userService->batchGet($openid) : $userService->get($openid);
        $userInfo = json_decode(json_encode($userInfo), true);
        return $userInfo;
    }
}
